package com.spring.core.wired;

import com.spring.core.annotation.Autowired;
import com.spring.core.context.AbstractApplicationContext;
import com.spring.core.context.AnnotationApplicationContext;
import com.spring.util.StringUtil;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;

/**
 * autowired 注解注入
 *
 * @author Zee
 * @version 1.0
 * @date 2021/10/13
 */
public class FieldAutowired implements Wired {

    @Override
    public void doWired(AbstractApplicationContext context) {
        System.out.println("依赖注入:@autowired");
        context.getIoc().values().forEach(v -> {
            Field[] fields = v.getClass().getDeclaredFields();
            for (Field field : fields) {
                //字段上面包含Autowired注解和设置值
                if (field.isAnnotationPresent(Autowired.class)) {
                    //强制访问权限
                    field.setAccessible(true);
                    Collection<?> values;
                    Autowired autowired = field.getAnnotation(Autowired.class);
                    String beanName = autowired.value();
                    if ("".equals(beanName)) {

                        beanName = field.getType().getSimpleName();
                    }
                    if (field.getType().isInterface()) {
                        values = context.getBeanOfType(field.getType()).values();
                        if (values.size() > 1) {
                            if ("".equals(autowired.value())) {
                                throw new RuntimeException("接口Bean注入 包含多个实例，应在AutoWired中指定beanName");
                            }
                        } else {
                            try {
                                field.set(v, values.stream().findFirst().get());
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            }
                        }
                    } else {
                        try {
                            Object bean = context.getBean(beanName);
                            if (Objects.isNull(bean)) {
                                throw new RuntimeException("未找到bean实例");
                            }
                            field.set(v, bean);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }

            }

        });

    }
}
